//-----------------------------------------------------------------------
// <copyright file="Modify.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-25</date>
// <summary>Modifies an existing Applcation Pool (IIS6 or later).</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Web.AppPool
{
    using System;
    using Microsoft.Build.Framework;
    using Web = Microsoft.Sdc.Tasks.Configuration.Web;

    /// <summary>
    /// Modifies an existing Applcation Pool (IIS6 or later).
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<Web.AppPool.Create AppPoolName="appPoolName" IdentityType="identityType" 
    /// Identity="identity" Password="password" IdleTimeout="idletimeout" PeriodicRestartTime="periodicRestartTime" WorkerProcesses="workerProcesses" />]]></code>
    /// <para>where:</para>
    /// <para><i>appPoolName (Required)</i></para>
    /// <para>Any existing IIS pool name</para>
    /// <para><i>identityType (Required)</i></para>
    /// <para>One of LocalSystem, LocalService, NetworkService, SpecifiedUserAccount</para>
    /// <para><i>identity (Required if identitytype is set to "SpecifiedUserAccount")</i></para>
    /// <para>Username to run the application pool as</para>
    /// <para><i>password (Required if identitytype is set to "SpecifiedUserAccount")</i></para>
    /// <para>Password for the application pool identity</para>
    /// <para><i>idletimeout</i></para>
    /// <para>The idle timeout (in minutes) for the application pool</para>
    /// <para><i>periodicRestartTime</i></para>
    /// <para>The periodic restart time (in minutes) for the application pool</para>
    /// <para><i>workerProcesses</i></para>
    /// <para>The number of worker processes for the application pool</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <Web.AppPool.Modify
    ///             AppPoolName="Existing Application Pool"
    ///             IdentityType="SpecifiedUserAccount"
    ///             Identity="pooluser"
    ///             Password="pool$1234"
    ///             IdleTimeout="40"
    ///             PeriodicRestartTime="60"
    ///             WorkerProcesses="1"
    ///            />
    ///     </Target>
    /// </Project>
    /// ]]></code>
    /// </example>    
    public class Modify : TaskBase
    {
        /// <summary>
        /// The name of the application pool to create.
        /// </summary>
        private string name;

        /// <summary>
        /// The identity type for this application pool.
        /// </summary>
        private string identityType;

        /// <summary>
        /// Username to run identity pool as. 
        /// Only used if <see cref="IdentityType">IdentityType</see> is SpecifiedUserAccount
        /// </summary>
        private string identity;

        /// <summary>
        /// Password for the Application Pool <see cref="Identity">identity</see>
        /// Only used if <see cref="IdentityType">IdentityType</see> is SpecifiedUserAccount
        /// </summary>
        private string password;

        /// <summary>
        /// The IdleTimeout metabase value in minutes, set to 0 to disable the idle time-out.
        /// </summary>
        private int idleTimeout;

        /// <summary>
        /// Specifies whether the IdleTimeout metabase value is set.
        /// </summary>
        private bool idleTimeoutSet = false;

        /// <summary>
        /// The PeriodicRestartTime metabase value in minutes, set to 0 to disable periodic restart.
        /// </summary>
        private int periodicRestartTime;

        /// <summary>
        /// Specifies whether the PeriodicRestartTime metabase value is set.
        /// </summary>
        private bool periodicRestartTimeSet = false;

        /// <summary>
        /// The MaxProcesses metabase value. Default is 1.
        /// </summary>
        private int workerProcesses;

        /// <summary>
        /// Specifies whether the MaxProcesses metabase value is set.
        /// </summary>
        private bool workerProcessesSet = false;

        private string machineName = "localhost";

        /// <summary>
        /// Machine to operate on
        /// </summary>
        public string MachineName
        {
            get { return this.machineName; }
            set { this.machineName = value; }
        }

        /// <summary>
        /// Name of the application pool to create
        /// </summary>
        /// <value>Any valid IIS application pool name</value>
        [Required]
        public string AppPoolName
        {
            get { return (this.name ?? String.Empty); }

            set { this.name = value; }
        }

        /// <summary>
        /// Identity type for this application pool
        /// </summary>
        /// <value>One of:
        /// LocalSystem 
        /// LocalService
        /// NetworkService
        /// SpecifiedUserAccount</value>
        [Required]
        public string IdentityType
        {
            get { return (this.identityType ?? String.Empty); }

            set { this.identityType = value; }
        }

        /// <summary>
        /// Username to run identity pool as. 
        /// Only used if <see cref="IdentityType">IdentityType</see> is SpecifiedUserAccount
        /// </summary>
        /// <value>A valid, existing AD/NT username</value>
        public string Identity
        {
            get { return (this.identity ?? String.Empty); }

            set { this.identity = value; }
        }

        /// <summary>
        /// Password for the Application Pool <see cref="Identity">identity</see>
        /// Only used if <see cref="IdentityType">IdentityType</see> is SpecifiedUserAccount
        /// </summary>
        /// <value>A valid password for the identity account</value>
        public string Password
        {
            get { return (this.password ?? String.Empty); }

            set { this.password = value; }
        }

        /// <summary>
        /// Used to configure the IdleTimeout metabase property
        /// </summary>
        /// <value>The IdleTimeout value in minutes, set to 0 to disable IdleTimeout</value>
        public int IdleTimeout
        {
            get
            {
                return this.idleTimeout;
            }

            set
            {
                this.idleTimeoutSet = true;
                this.idleTimeout = value;
            }
        }

        /// <summary>
        /// Gets or sets the PeriodicRestartTime metabase property.
        /// </summary>
        /// <value>The PeriodicRestartTime value in minutes, set to 0 to disable periodic restart.</value>
        public int PeriodicRestartTime
        {
            get
            {
                return this.periodicRestartTime;
            }

            set
            {
                this.periodicRestartTimeSet = true;
                this.periodicRestartTime = value;
            }
        }

        /// <summary>
        /// Gets or sets the MaxProcesses metabase value. Default is 1.
        /// </summary>
        public int WorkerProcesses
        {
            get
            {
                return this.workerProcesses;
            }

            set
            {
                this.workerProcessesSet = true;
                this.workerProcesses = value;
            }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            if (!Web.AppPool.Exists(this.name, this.MachineName))
            {
                Log.LogError("Web.AppPoolDoesNotExist", this.name);
            }
            else
            {
                Log.LogMessageFromResources("Web.ModifyAppPool", this.name);

                Web.AppPool appPool = Web.AppPool.Load(this.name, this.MachineName);

                if (this.identityType != null)
                {
                    appPool.Identity.Type = (Web.AppPoolIdentityType) Enum.Parse(typeof(Web.AppPoolIdentityType), this.identityType, true);
                }

                if (this.identity != null)
                {
                    appPool.Identity.Name = this.identity;
                    appPool.Identity.Password = this.password;
                }

                // Performance
                if (this.idleTimeoutSet)
                {
                    appPool.Performance.IdleTimeout = this.idleTimeout;
                }
                else
                {
                    this.idleTimeout = appPool.Performance.IdleTimeout;
                }

                if (this.workerProcessesSet)
                {
                    appPool.Performance.WorkerProcesses = this.workerProcesses;
                }
                else
                {
                    this.workerProcesses = appPool.Performance.WorkerProcesses;
                }

                // Recycling
                if (this.periodicRestartTimeSet)
                {
                    appPool.Recycling.RestartTime = this.periodicRestartTime;
                }
                else
                {
                    this.periodicRestartTime = appPool.Recycling.RestartTime;
                }

                appPool.Save();
            }
        }
    }
}